package com.cloud.service;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * @author: ZhangKaiQiang
 * @date: 2021/4/15
 * @time: 17:51
 *
 *
 * 实际加锁 解锁的Service
 **/
public class RLockClient {

    private Logger logger= LoggerFactory.getLogger(RLockClient.class);

    private RedissonClient redissonClient;


    public RLockClient(RedissonClient redissonClient){
        this.redissonClient=redissonClient;
    }


    /**
     * 加锁
     * @param lockName 锁名称
     * @param leaseTime 释放时间
     * @param timeUnit 释放时间单位
     */
    public void lock(String lockName, int leaseTime, TimeUnit timeUnit){
        if (StringUtils.isEmpty(lockName)){
            logger.info("尝试获取锁时,lockName is null",lockName);
        }
        RLock lock = redissonClient.getLock(lockName);
        lock.lock(leaseTime,timeUnit);
    }


    /**
     * 解锁操作
     * @param lockName 锁名称
     */
    public void unLock(String lockName){
        if (StringUtils.isEmpty(lockName)){
            logger.info("解锁时,lockName is null");
        }
        RLock lock = redissonClient.getLock(lockName);
        lock.unlock();
    }


    /**
     * 尝试获取锁
     * @param lockName 锁名称
     * @param waitTime 等待时间
     * @param leaseTime 释放时间
     * @param timeUnit 时间单位
     * @return true:获取锁成功 false:获取锁失败
     */
    public boolean tryLock(String lockName,long waitTime,long leaseTime,TimeUnit timeUnit){
        if (StringUtils.isEmpty(lockName)){
            logger.info("尝试获取锁时,lockName is null ,ThreadName:{}",Thread.currentThread().getName());
            return false;
        }
        RLock lock = redissonClient.getLock(lockName);
        try {
            boolean lockResult = lock.tryLock(waitTime, leaseTime,timeUnit);
            return lockResult;
        } catch (InterruptedException e) {
            logger.info("尝试获取锁时发生InterruptedException异常,ThreadName:{}",Thread.currentThread().getName());
        }
        return false;
    }


    /**
     * 判断该线程是否持有当前锁
     * @param lockName  锁名称
     */
    public boolean isHeldByCurrentThread(String lockName) {
        if (StringUtils.isEmpty(lockName)){
            logger.info("判断当前线程是否持有锁时锁名称为null,ThreadName:{}",Thread.currentThread().getName());
        }
        RLock rLock = redissonClient.getLock(lockName);
        return rLock.isHeldByCurrentThread();
    }



    /**
     * 判断该锁是否已经被线程持有
     * @param lockName  锁名称
     */
    public boolean isLock(String lockName) {
        if (StringUtils.isEmpty(lockName)){
            logger.info("判断该锁是否已经被线程持有时锁名称为null,ThreadName:{}",Thread.currentThread().getName());
        }
        RLock rLock = redissonClient.getLock(lockName);
        return rLock.isLocked();
    }







}
